import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;


public class HypothesisGenerator {

	ArrayList<ContingencyTable> miningTables;
	
	static double pQuantifier = 0.25;
	static int tMinMatch = 5;
	
	public HypothesisGenerator( ArrayList<ArrayList<Integer>> ante, ArrayList<ArrayList<Integer>> succ )
	{
		miningTables = new ArrayList<ContingencyTable>();
		for (int i = 0; i< ante.size(); i++)
		{
			contructorHelper( ante.get(i), succ.get(i) );
		}
	}
	
	private void contructorHelper( ArrayList<Integer> ante, ArrayList<Integer> succ )
	{
	
		ArrayList<ArrayList<Integer>> allAnte = getCombinatations( ante, ante.size()-1, 0, ante.size()/2 );
		
		ArrayList<ArrayList<Integer>> allSucc = getCombinatations( succ, succ.size()-1, 0, succ.size()/2 );
		
		for ( ArrayList<Integer> trueAnte : allAnte)
		{
			ArrayList<Integer> falseAnte = getFalse(ante, trueAnte);
			for ( ArrayList<Integer> trueSucc : allSucc)
			{
				ArrayList<Integer> falseSucc = getFalse(succ, trueSucc);
				HypothesisParameters hypothesis = new HypothesisParameters(trueAnte, falseAnte, trueSucc, falseSucc);
				miningTables.add( new ContingencyTable(hypothesis));
			}			
		}
	}
	
	public HypothesisGenerator( ArrayList<HypothesisParameters> hypotheses )
	{
		miningTables = new ArrayList<ContingencyTable>();
		for (HypothesisParameters hypthesis: hypotheses)
		{
			miningTables.add( new ContingencyTable(hypthesis));
		}	
	}

	public static void main(String[] args) {
		
		ArrayList<Integer> allCedents = new ArrayList<Integer>();
		allCedents.add(1);
		allCedents.add(2);
		allCedents.add(3);
		allCedents.add(4);
		allCedents.add(5);
		
		System.out.println("Test 1");
		HypothesisGenerator hg = new HypothesisGenerator(new ArrayList<HypothesisParameters>());
		ArrayList<ArrayList<Integer>> allAnte = hg.getCombinatations(allCedents, allCedents.size()-1 , 0, 2) ;
		for ( ArrayList<Integer> array : allAnte)
		{
			System.out.println( hg.getFalse(allCedents, array) );
		}
	
	}
	
	private ArrayList<Integer> getFalse(  ArrayList<Integer> allCedent, ArrayList<Integer> trueCedent)
	{
		ArrayList<Integer> falseCedent = new ArrayList<Integer>();
		int i =0;
		for( int element : allCedent)
		{
			if ( i< trueCedent.size() && element == trueCedent.get(i))
			{
				i++;
			}
			else
			{
				falseCedent.add(element);
			}
				
		}
		return falseCedent;
	}
	
	private ArrayList<ArrayList<Integer>> getCombinatations( ArrayList<Integer> allCedents, int start, int currentFalse, int maxFalse )
	{
		if (start < 0 )
		{
			ArrayList<ArrayList<Integer>> base =  new ArrayList<ArrayList<Integer>>();
			base.add( new ArrayList<Integer>() );
			return base;			
		}
		ArrayList<ArrayList<Integer>> smallCombosTrue = getCombinatations( allCedents, start-1, currentFalse, maxFalse );
		ArrayList<ArrayList<Integer>> smallCombosFalse = new ArrayList<ArrayList<Integer>>();
		if (currentFalse < maxFalse)
			smallCombosFalse = getCombinatations( allCedents, start-1, currentFalse+1, maxFalse );
		
		
		for( ArrayList<Integer> combo: smallCombosTrue )
		{
			int val = allCedents.get(start);
			combo.add(val);
		}
		
		smallCombosTrue.addAll(smallCombosFalse);
		
		return smallCombosTrue;
	}
	
	public void testHypotheses(ArrayList<SongBits> songData)
	{
		PrintWriter output = null;
		try {
			output = new PrintWriter(new FileWriter("output.txt"));
		
			for( SongBits song : songData)
			{
				for( ContingencyTable table: miningTables)
				{	
					table.countSong(song);
				}		
			}		
			
			
			for(ContingencyTable table: miningTables)
			{	
				String result = table.getResult(pQuantifier, tMinMatch, output);
				if (result != null && !result.isEmpty())
				{
					System.out.println(result);
					output.println("FOUND: " + result + "\n");
				}
			}
			output.close();
		}
		catch (IOException e) {
			e.printStackTrace();
		}
		
	}
}
